package service

import (
	"encoding/json"

	"agentdesign/models"
)

// CreatePromptRequest stores a new prompt request row.
func (s *ApiService) CreatePromptRequest(pr models.PromptRequest) (models.PromptRequest, error) {
	if pr.ID == "" {
		if err := s.db.Get(&pr.ID, "SELECT UUID()"); err != nil {
			return models.PromptRequest{}, err
		}
	}

	if pr.Status == "" {
		pr.Status = "pending"
	}

	projectID := nullableString(pr.ProjectID)
	pageID := nullableString(pr.PageID)
	generatedVersionID := nullableString(pr.GeneratedVersionID)
	createdBy := nullableString(pr.CreatedBy)

	_, err := s.db.Exec(`
		INSERT INTO prompt_requests (id, project_id, page_id, prompt_text, status, model_name, generated_version_id, created_by)
		VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
		pr.ID,
		projectID,
		pageID,
		pr.PromptText,
		pr.Status,
		pr.ModelName,
		generatedVersionID,
		createdBy,
	)
	if err != nil {
		return models.PromptRequest{}, err
	}

	return s.GetPromptRequest(pr.ID)
}

// GetPromptRequest fetches a prompt request by id.
func (s *ApiService) GetPromptRequest(id string) (models.PromptRequest, error) {
	record := models.PromptRequest{}
	err := s.db.Get(&record, `
		SELECT id, project_id, page_id, prompt_text, COALESCE(response_json, 'null') AS response_json, status, model_name, generated_version_id, created_by, created_at
		FROM prompt_requests
		WHERE id = ?`, id)

	return record, err
}

// MarkPromptRequestCompleted stores the response payload and marks the request finished.
func (s *ApiService) MarkPromptRequestCompleted(id string, response json.RawMessage) error {
	_, err := s.db.Exec(`
		UPDATE prompt_requests
		SET response_json = ?, status = 'completed'
		WHERE id = ?`,
		response,
		id,
	)
	return err
}

// MarkPromptRequestFailed records the failure message.
func (s *ApiService) MarkPromptRequestFailed(id string, errMsg string) error {
	payload, _ := json.Marshal(map[string]string{"error": errMsg})
	_, err := s.db.Exec(`
		UPDATE prompt_requests
		SET response_json = ?, status = 'failed'
		WHERE id = ?`,
		payload,
		id,
	)
	return err
}

func nullableString(value *string) any {
	if value == nil || *value == "" {
		return nil
	}
	return *value
}
